#version 120

#extension GL_EXT_geometry_shader4 : enable

uniform float pointRadius;  // point size in world space
void main()
{
    gl_FrontColor = gl_FrontColorIn[0];

    // eye space
    vec3 pos = gl_PositionIn[0].xyz;
    vec3 pos2 = gl_TexCoordIn[0][0].xyz;
    vec3 motion = pos - pos2;
    vec3 dir = normalize(motion);
    float len = length(motion);

    vec3 x = dir * pointRadius;
    vec3 view = normalize(-pos);
    vec3 y = normalize(cross(dir, view)) * pointRadius;
    float facing = dot(view, dir);

    // check for very small motion to avoid jitter
    float threshold = 0.01;
    if ((len < threshold) || (facing > 0.95) || (facing < -0.95)) {
        pos2 = pos;
        x = vec3(pointRadius, 0.0, 0.0);
        y = vec3(0.0, -pointRadius, 0.0);
    }
    
    // output quad
    gl_TexCoord[0] = vec4(0, 0, 0, 0);
    gl_TexCoord[1] = gl_PositionIn[0];
    gl_Position = gl_ProjectionMatrix * vec4(pos + x + y, 1);
    EmitVertex();

    gl_TexCoord[0] = vec4(0, 1, 0, 0);
    gl_TexCoord[1] = gl_PositionIn[0];
    gl_Position = gl_ProjectionMatrix * vec4(pos + x - y, 1);
    EmitVertex();

    gl_TexCoord[0] = vec4(1, 0, 0, 0);
    gl_TexCoord[1] = gl_PositionIn[0];
    gl_Position = gl_ProjectionMatrix * vec4(pos2 - x + y, 1);
    EmitVertex();

    gl_TexCoord[0] = vec4(1, 1, 0, 0);
    gl_TexCoord[1] = gl_PositionIn[0];
    gl_Position = gl_ProjectionMatrix * vec4(pos2 - x - y, 1);
    EmitVertex();
}